package com.archermind.nfc.client.transport;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.util.Log;

import com.archermind.nfc.common.model.Message;
import com.archermind.nfc.common.model.Message.MessageType;

public class MessageHandler extends IoHandlerAdapter {

	private static final String TAG = "MessageHandler";

	private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());

	private Map<Integer, Message> mRequestMap = new ConcurrentHashMap<Integer, Message>();
	private Map<Integer, Message> mReplyMap = new ConcurrentHashMap<Integer, Message>();

	public void sessionOpened(IoSession session) throws Exception {
		logger.info("client session opened");
	}

	public void sessionClosed(IoSession session) {
		logger.info("client session closed");
	}

	public void messageReceived(IoSession session, Object obj) throws Exception {
		Log.d(TAG, obj.toString());

		if (obj instanceof Message) {
			Message message = (Message) obj;
			if (message.getMessageType() == MessageType.REQUEST) {

			} else if (message.getMessageType() == MessageType.REPLY) {
				Message requestMessage = mRequestMap
						.get(message.getMessageId());
				if (requestMessage == null) {
					return;
				}

				mReplyMap.put(message.getMessageId(), message);

				synchronized (requestMessage) {
					requestMessage.notify();
				}
			}
		} else {
			logger.error("Received unrecognized message: " + obj);
		}
	}

	public void messageSent(IoSession arg0, Object arg1) throws Exception {
	}

	public Message getReplyMessage(int messageId) {
		if (messageId == 0) {
			throw new RuntimeException("Message id was not set.");
		}

		Message replyMessage = mReplyMap.get(messageId);
		mReplyMap.remove(messageId);

		return replyMessage;
	}

	public void putRequestMessage(Message message) {
		if (message == null || message.getMessageId() == 0) {
			throw new RuntimeException(
					"Message is null or message id was not set.");
		}

		mRequestMap.put(message.getMessageId(), message);
	}

	public void removeRequestMessage(int messageId) {
		if (messageId == 0) {
			throw new RuntimeException("Message id was not set.");
		}

		mRequestMap.remove(messageId);
	}

}